{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'newaxis' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-14-642fd8355540>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mnewaxis\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'newaxis' is not defined"
     ]
    }
   ],
   "source": [
    "newaxis is None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "a = np.array([1, 2, 3 ,4])\n",
    "print(a)\n",
    "#一般使用numpy来生成一个向量，但其默认生成的是行向量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1 2 3 4]\n"
     ]
    }
   ],
   "source": [
    "a = np.array([1, 2, 3, 4])\n",
    "print(a.transpose())\n",
    "#从输出可见，转置对一维数组是无效的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1]\n",
      " [2]\n",
      " [3]\n",
      " [4]]\n",
      "(4, 1)\n",
      "\n",
      "\n",
      "[[1 2 3 4]]\n",
      "(1, 4)\n",
      "\n",
      "\n",
      "[[[1]]\n",
      "\n",
      " [[2]]\n",
      "\n",
      " [[3]]\n",
      "\n",
      " [[4]]]\n",
      "(4, 1, 1)\n",
      "\n",
      "\n",
      "[[[1 2 3 4]]]\n",
      "(1, 1, 4)\n",
      "\n",
      "\n",
      "[1 2 3 4]\n",
      "(4,)\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "A = np.array([1, 2, 3, 4])\n",
    "# np.newaxis的作用是增加一个维度，A[:, np.newaxis]是在列方向增加一个维度，A[np.newaxis,:]是在行方向增加一个维度\n",
    "# 具体输出如下，PS：这个确实不好理解\n",
    "A_t = A[:, np.newaxis]\n",
    "B_t = A[np.newaxis,:]\n",
    "C_t = A[:, np.newaxis, np.newaxis]\n",
    "D_t = A[np.newaxis, np.newaxis, :]\n",
    "print(A_t)\n",
    "print(A_t.shape)\n",
    "print(\"\\n\")\n",
    "print(B_t)\n",
    "print(B_t.shape)\n",
    "print(\"\\n\")\n",
    "print(C_t)\n",
    "print(C_t.shape)\n",
    "print(\"\\n\")\n",
    "print(D_t)\n",
    "print(D_t.shape)\n",
    "print(\"\\n\")\n",
    "print(A)\n",
    "print(A.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2 3 4]]\n",
      "[[1]\n",
      " [2]\n",
      " [3]\n",
      " [4]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1, 2, 3, 4]])\n",
    "print(A)\n",
    "print(A.T)\n",
    "# 使用了numpy的二维数组的初始化方法,这个初始化方法以后经常会用\n",
    "# 但是默认生成的是行向量，这时二维数组可以看作一个矩阵，\n",
    "# 就可以直接通过行向量转置的方法来生成对应的行向量了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 6]\n",
      " [ 8]\n",
      " [10]]\n"
     ]
    }
   ],
   "source": [
    "u = np.array([[1, 2, 3]]).T\n",
    "v = np.array([[5, 6, 7]]).T\n",
    "print(u+v)\n",
    "# 向量的加法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[3]\n",
      " [6]\n",
      " [9]]\n"
     ]
    }
   ],
   "source": [
    "u = np.array([[1, 2, 3]]).T\n",
    "print(3*u)\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 注意：第一种情况下，两个一维数组表示的，无论是行向量还是列向量，都可以直接使用np.dot（）进行点乘；\n",
    "### 但是第二种情况，由于二维数组表示的是矩阵，那么在点乘时，也应该按照矩阵的点乘法则（mxn·nxm）来进行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "38\n",
      "38\n",
      "38\n",
      "[[38]]\n"
     ]
    }
   ],
   "source": [
    "u = np.array([1, 2, 3])\n",
    "v = np.array([5, 6, 7])\n",
    "print(u.dot(v))\n",
    "print(np.dot(u,v))\n",
    "print(np.dot(u.T,v.T))\n",
    "# 对一维数组表示的行向量进行点乘（dot,inner）\n",
    "u = np.array([[1, 2, 3]])\n",
    "v = np.array([[5, 6, 7]]).T\n",
    "print(np.dot(u,v))\n",
    "# 对二维数组表示的矩阵进行点乘"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 注意：矩阵的内积、外积与向量的内积、外积是不一样的，在理解上很容易弄错\n",
    "### 向量的内积是一个值，是点乘用np.dot()\n",
    "### 向量的外积是叉乘用np.cross()\n",
    "### 矩阵的内积是一个值，是矩阵对应元素乘积之和，既不是点乘也不是叉乘，用np.multiply()，也可以用直接用运算符 *\n",
    "### 矩阵的外积是一个矩阵，利用线性代数中的四种求积方法求得的，是点乘，用np.dot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[23 29 38]\n",
      " [35 44 57]\n",
      " [59 74 95]]\n",
      "[[ 5 12 21]\n",
      " [ 6 12 20]\n",
      " [16 25 42]]\n",
      "[[ 5 12 21]\n",
      " [ 6 12 20]\n",
      " [16 25 42]]\n",
      "[[-4  8 -4]\n",
      " [-1  2 -1]\n",
      " [ 5 -4  0]]\n",
      "[ 5 11]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "u = np.array([[1, 2, 3],\n",
    "            [2, 3, 4],\n",
    "            [4, 5, 6]])\n",
    "v = np.array([[5, 6, 7],\n",
    "            [3, 4, 5],\n",
    "            [4, 5, 7]])\n",
    "print(np.dot(u,v))\n",
    "print(np.multiply(u,v))\n",
    "print(u*v)\n",
    "print(np.cross(u,v))\n",
    "a=np.array([[1, 2],[3, 4]])\n",
    "b=np.array([[-1, 3],[-2, 1]])\n",
    "print(np.cross(a,b))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-4\n",
      "[-4  8 -4]\n"
     ]
    }
   ],
   "source": [
    "u = np.array([1, 2])\n",
    "v = np.array([5, 6])\n",
    "print(np.cross(u, v))\n",
    "\n",
    "u = np.array([1, 2, 3])\n",
    "v = np.array([5, 6, 7])\n",
    "print(np.cross(u, v))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[63]\n",
      " [75]\n",
      " [87]]\n"
     ]
    }
   ],
   "source": [
    "u = np.array([[1, 2, 3]]).T\n",
    "v = np.array([[5, 6, 7]]).T\n",
    "w = np.array([[8, 9, 10]]).T\n",
    "print(3*u+4*v+5*w)\n",
    "# 向量的线性组合"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 2]\n",
      " [3 4]\n",
      " [5 6]\n",
      " [7 8]]\n",
      "(4, 2)\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1, 2],\n",
    "             [3, 4],\n",
    "             [5, 6],\n",
    "             [7, 8]])\n",
    "print(A)\n",
    "print(A.shape)\n",
    "# 在形容矩阵的形状和规模的时候，一般采用其行数和列数来进行描述\n",
    "# 通过矩阵A的shape属性，shape属性，shape属性，就可以获取一个表示规模的元组对象，第一个表示行数，第二个表示列数\n",
    "# 注意：shape是属性不是方法，所以没有后面那个括号"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0. 0. 0.]\n",
      " [0. 0. 0.]\n",
      " [0. 0. 0.]\n",
      " [0. 0. 0.]\n",
      " [0. 0. 0.]]\n"
     ]
    }
   ],
   "source": [
    "A = np.zeros([5, 3])\n",
    "print(A)\n",
    "# 可以向np的zeros函数传入一个元组对象，第一个表示行数，第二个表示列数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1 0 0 0 0]\n",
      " [0 2 0 0 0]\n",
      " [0 0 3 0 0]\n",
      " [0 0 0 4 0]\n",
      " [0 0 0 0 5]]\n"
     ]
    }
   ],
   "source": [
    "A = np.diag([1, 2, 3, 4, 5])\n",
    "print(A)\n",
    "# np的diag函数可以用来生成一个对角矩阵，元组中的元素分别是对角线上依次元素的值\n",
    "# diag is the abbreviation of diagonal matrix"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[11 14 17 20]\n",
      " [23 30 37 44]\n",
      " [35 46 57 68]\n",
      " [47 62 77 92]]\n"
     ]
    }
   ],
   "source": [
    "A = np.array([[1,2],\n",
    "             [3,4],\n",
    "             [5,6],\n",
    "             [7,8]])\n",
    "B = np.array([[1,2,3,4],\n",
    "            [5,6,7,8]])\n",
    "print(np.dot(A,B))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n",
      "2\n",
      "1\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "A_1 = np.array([[1, 1, 0],\n",
    "               [1, 0, 1]])\n",
    "A_2 = np.array([[1, 2, -1],\n",
    "               [2, 4, -2]])\n",
    "A_3 = np.array([[1, 0],\n",
    "               [0, 1],\n",
    "               [0, -1]])\n",
    "A_4 = np.array([[1, 2],\n",
    "               [1, 2],\n",
    "               [-1, -2]])\n",
    "A_5 = np.array([[1, 1, 1],\n",
    "               [1, 1, 2],\n",
    "               [1, 2, 3]])\n",
    "print(np.linalg.matrix_rank(A_1))\n",
    "print(np.linalg.matrix_rank(A_2))\n",
    "print(np.linalg.matrix_rank(A_3))\n",
    "print(np.linalg.matrix_rank(A_4))\n",
    "print(np.linalg.matrix_rank(A_5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[  1.    -17.5    13.125]\n",
      " [  0.      0.5    -0.375]\n",
      " [  0.      0.      0.25 ]]\n",
      "[[1. 0. 0.]\n",
      " [0. 1. 0.]\n",
      " [0. 0. 1.]]\n"
     ]
    }
   ],
   "source": [
    "from scipy import linalg\n",
    "A = np.array([[1, 35, 0],4131\n",
    "             [0, 2, 3],\n",
    "             [0, 0, 4]])\n",
    "A_n = linalg.inv(A) # inv is the abbreviation of inverse\n",
    "print(A_n)\n",
    "print(np.dot(A, A_n))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "ename": "LinAlgError",
     "evalue": "singular matrix",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mLinAlgError\u001b[0m                               Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-6-e959b07368da>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m      2\u001b[0m             \u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m3\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      3\u001b[0m             [1, 1, 5]])\n\u001b[0;32m----> 4\u001b[0;31m \u001b[0mB_n\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlinalg\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minv\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mB\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m      5\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mB\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mB_n\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;32m~/anaconda3/lib/python3.8/site-packages/scipy/linalg/basic.py\u001b[0m in \u001b[0;36minv\u001b[0;34m(a, overwrite_a, check_finite)\u001b[0m\n\u001b[1;32m    975\u001b[0m         \u001b[0minv_a\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minfo\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgetri\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlu\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpiv\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlwork\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mlwork\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moverwrite_lu\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    976\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0minfo\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 977\u001b[0;31m         \u001b[0;32mraise\u001b[0m \u001b[0mLinAlgError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"singular matrix\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    978\u001b[0m     \u001b[0;32mif\u001b[0m \u001b[0minfo\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    979\u001b[0m         raise ValueError('illegal value in %d-th argument of internal '\n",
      "\u001b[0;31mLinAlgError\u001b[0m: singular matrix"
     ]
    }
   ],
   "source": [
    "B = np.array([[1, 0, 2],\n",
    "            [0, 1, 3],\n",
    "            [1, 1, 5]])\n",
    "B_n = linalg.inv(B)\n",
    "print(B)\n",
    "print(B_n)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1. 2. 3.]\n",
      "[ 0. -0.  0.]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from scipy import linalg\n",
    "A = np.array([[1, 2, 3],\n",
    "             [1, -1, 4],\n",
    "             [2, 3, -1]])\n",
    "y = np.array([14, 11, 5])\n",
    "x = linalg.solve(A, y)\n",
    "print(x)\n",
    "z = np.array([0, 0, 0])\n",
    "w = linalg.solve(A, z)\n",
    "print(w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3.+0.j 1.+0.j]\n",
      "[[ 0.70710678 -0.70710678]\n",
      " [ 0.70710678  0.70710678]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "from scipy import linalg\n",
    "A = np.array([[2, 1],\n",
    "             [1, 2]])\n",
    "evalue, evector = linalg.eig(A)\n",
    "print(evalue)\n",
    "print(evector)\n",
    "# 使用linalg.eig来求解A的特征值和特征向量，特征值返回给evalue，特征向量返回给evector\n",
    "# evalue里有j显然是可能有复数的特征值\n",
    "# 特征向量看起来很别扭，是因为python将结果处理丞模长为1的单位向量了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[1.+0.j 2.+0.j 5.+0.j]\n",
      "[[1. 0. 0.]\n",
      " [0. 1. 0.]\n",
      " [0. 0. 1.]]\n"
     ]
    }
   ],
   "source": [
    "B = np.array([[1, 0, 0],\n",
    "             [0, 2, 0],\n",
    "             [0, 0, 5]])\n",
    "evalue, evector = linalg.eig(B)\n",
    "print(evalue)\n",
    "print(evector)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-2.+0.j  5.+0.j  5.+0.j]\n",
      "[[-0.89442719 -0.83205029  0.        ]\n",
      " [ 0.4472136  -0.5547002   0.        ]\n",
      " [ 0.          0.          1.        ]]\n"
     ]
    }
   ],
   "source": [
    "B = np.array([[1, 6, 0],\n",
    "             [2, 2, 0],\n",
    "             [0, 0, 5]])\n",
    "evalue, evector = linalg.eig(B)\n",
    "print(evalue)\n",
    "print(evector)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[6.+0.j 4.+0.j 6.+0.j]\n",
      "[[ 1.00000000e+00  7.07106781e-01 -1.00000000e+00]\n",
      " [ 0.00000000e+00  7.07106781e-01  0.00000000e+00]\n",
      " [ 0.00000000e+00  0.00000000e+00  1.33226763e-15]]\n"
     ]
    }
   ],
   "source": [
    "C = np.array([[6, -2, 1],\n",
    "             [0, 4, 0],\n",
    "             [0, 0, 6]])\n",
    "evalue, evector = linalg.eig(C)\n",
    "print(evalue)\n",
    "print(evector)\n",
    "# 由于机器运算的结果，结果中的1.33e-15可视作0，所以6的特征向量是线性相关的，故C不可逆，则不可对角化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 8.33888363e-17 -5.34522484e-01 -8.19688300e-01 -1.42578545e-02\n",
      "   1.17589781e-01 -1.68291600e-01  6.64076653e-03]\n",
      " [-5.27910020e-33 -8.01783726e-01  4.81453408e-01 -3.68497530e-03\n",
      "  -3.51336168e-01 -4.34953513e-02  1.71632139e-03]\n",
      " [ 0.00000000e+00 -2.67261242e-01  1.95016375e-01  3.95706349e-02\n",
      "   8.18828941e-01  4.67069254e-01 -1.84304972e-02]\n",
      " [-1.79605302e-01  4.55126095e-17  8.85078821e-02  8.82844675e-01\n",
      "   1.60750385e-01 -3.92953497e-01  1.55058983e-02]\n",
      " [-3.59210604e-01  6.56005654e-17  1.77015764e-01 -4.17392305e-01\n",
      "   3.21500770e-01 -6.18874662e-01 -4.23140914e-01]\n",
      " [-8.98026510e-01  1.48333183e-18 -1.06209459e-01  3.21272177e-02\n",
      "  -1.92900462e-01  3.79211394e-01 -1.49636365e-02]\n",
      " [-1.79605302e-01  3.28002827e-17  8.85078821e-02 -2.08696153e-01\n",
      "   1.60750385e-01 -2.65354150e-01  9.05594112e-01]]\n",
      "[9.64365076e+00 5.29150262e+00 6.49628424e-16 1.43063514e-16\n",
      " 2.79192092e-17]\n",
      "[[-5.77350269e-01 -5.77350269e-01 -5.77350269e-01  0.00000000e+00\n",
      "   0.00000000e+00]\n",
      " [-1.70408510e-16  8.52042552e-17  8.52042552e-17 -7.07106781e-01\n",
      "  -7.07106781e-01]\n",
      " [-6.19518612e-01 -1.50835436e-01  7.70354049e-01  2.48999108e-16\n",
      "   1.37976805e-16]\n",
      " [-0.00000000e+00  8.56793076e-17 -8.56793076e-17  7.07106781e-01\n",
      "  -7.07106781e-01]\n",
      " [ 5.31848997e-01 -8.02443355e-01  2.70594358e-01  5.04241948e-17\n",
      "  -6.05981077e-17]]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "A = [[0, 0, 0, 2, 2],\n",
    "    [0, 0, 0, 3, 3],\n",
    "    [0, 0, 0, 1, 1],\n",
    "    [1, 1, 1, 0, 0],\n",
    "    [2, 2, 2, 0, 0],\n",
    "    [5, 5, 5, 0, 0],\n",
    "    [1, 1, 1, 0, 0]]\n",
    "\n",
    "U, sigma, VT = np.linalg.svd(A)\n",
    "print(U)\n",
    "print(sigma)\n",
    "print(VT)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 不难看出，五个奇异值的前两个奇异值在数值上占有绝对的优势，所以选择K=2进行行压缩和列压缩"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[-5.56776436e+00 -5.56776436e+00 -5.56776436e+00  1.66777673e-16\n",
      "   1.66777673e-16]\n",
      " [ 2.16930682e-16  2.16930682e-16  2.16930682e-16 -3.74165739e+00\n",
      "  -3.74165739e+00]]\n",
      "[[ 0.00000000e+00 -2.82842712e+00]\n",
      " [ 0.00000000e+00 -4.24264069e+00]\n",
      " [ 0.00000000e+00 -1.41421356e+00]\n",
      " [-1.73205081e+00  1.23259516e-32]\n",
      " [-3.46410162e+00  2.46519033e-32]\n",
      " [-8.66025404e+00  4.93038066e-32]\n",
      " [-1.73205081e+00  1.23259516e-32]]\n"
     ]
    }
   ],
   "source": [
    "U_T_2x7 = U.T[:2,:]\n",
    "print(np.dot(U_T_2x7,A))\n",
    "VT_2x5=VT[:2,:]\n",
    "print(np.dot(VT_2x5,np.mat(A).T).T)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 1.76986622e-17 -7.05283417e-16 -7.05283417e-16  2.00000000e+00\n",
      "   2.00000000e+00]\n",
      " [ 7.22982080e-16 -3.61491040e-16 -3.61491040e-16  3.00000000e+00\n",
      "   3.00000000e+00]\n",
      " [ 2.40994027e-16 -1.20497013e-16 -1.20497013e-16  1.00000000e+00\n",
      "   1.00000000e+00]\n",
      " [ 1.00000000e+00  1.00000000e+00  1.00000000e+00 -1.70292592e-16\n",
      "  -1.70292592e-16]\n",
      " [ 2.00000000e+00  2.00000000e+00  2.00000000e+00 -2.45454840e-16\n",
      "  -2.45454840e-16]\n",
      " [ 5.00000000e+00  5.00000000e+00  5.00000000e+00 -5.55011948e-18\n",
      "  -5.55011948e-18]\n",
      " [ 1.00000000e+00  1.00000000e+00  1.00000000e+00 -1.22727420e-16\n",
      "  -1.22727420e-16]]\n"
     ]
    }
   ],
   "source": [
    "A = [[0, 0, 0, 2, 2],\n",
    "    [0, 0, 0, 3, 3],\n",
    "    [0, 0, 0, 1, 1],\n",
    "    [1, 1, 1, 0, 0],\n",
    "    [2, 2, 2, 0, 0],\n",
    "    [5, 5, 5, 0, 0],\n",
    "    [1, 1, 1, 0, 0]]\n",
    "\n",
    "U, sigma, VT = np.linalg.svd(A)\n",
    "A_1 = sigma[0]*np.dot(np.mat(U[:, 0]).T, np.mat(VT[0, :]))\n",
    "A_2 = sigma[1]*np.dot(np.mat(U[:, 1]).T, np.mat(VT[1, :]))\n",
    "print(A_1+A_2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-6-7eb0a9a5c217>, line 5)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-6-7eb0a9a5c217>\"\u001b[0;36m, line \u001b[0;32m5\u001b[0m\n\u001b[0;31m    [0,0,0,0,0,0,0,0,0,3,0],\u001b[0m\n\u001b[0m    ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "scoreData = np.mat([\n",
    "[5,2,1,4,0,0,2,4,0,0,0],\n",
    "[0,0,0,0,0,0,0,0,0,3,0],\n",
    "[1,0,5,2,0,0,3,0,3,0,1],\n",
    "[0,5,0,0,4,0,1,0,0,0,0],\n",
    "[0,0,0,0,0,4,0,0,0,4,0],\n",
    "[0,0,1,0,0,0,1,0,0,5,0],\n",
    "[5,0,2,4,2,1,0,3,0,1,0],\n",
    "[0,4,0,0,5,4,0,0,0,0,5],\n",
    "[0,0,0,0,0,0,4,0,4,5,0],\n",
    "[0,0,0,4,0,0,1,5,0,0,0],\n",
    "[0,0,0,0,4,5,0,0,0,0,3],\n",
    "[4,2,1,4,0,0,2,4,0,0,0],\n",
    "[0,1,4,1,2,1,5,0,5,0,0],\n",
    "[0,0,0,0,0,4,0,0,0,4,0],\n",
    "[2,5,0,0,4,0,0,0,0,0,0],\n",
    "[5,0,0,0,0,0,0,4,2,0,0],\n",
    "[0,2,4,0,4,3,4,0,0,0,0],\n",
    "[0,3,5,1,0,0,4,1,0,0,0]])\n",
    "\n",
    "//计算余弦相似度，来定量分析商品与商品之间的相似程度\n",
    "def cosSim(vec_1, vec_2):\n",
    "    dotProd = float(np.dot(vec_1.T, vec_2))\n",
    "    normProd = np.linalg.norm(vec_1)*np.linalg.norm(vec_2)\n",
    "    return 0.5+0.5*(dotProd/normProd)\n",
    "\n",
    "// n-菜品总个数，simSum-itemIndex菜品与其他已打分菜品相似度的和\n",
    "// simSumScore-itemIndex菜品与其他已打分菜品的加权相似度之和\n",
    "def estScore(scoreData, scoreDataRC, userIndex, itemIndex):\n",
    "    n = np.shape(scoreData)[1]\n",
    "    simSum = 0\n",
    "    simSumScore = 0\n",
    "    for i in range(n):\n",
    "        userScore = scoreData[userIndex, i]\n",
    "        if userScore == 0 or i == itemIndex:\n",
    "            continue\n",
    "        sim = cosSim(scoreData[:,i], scoreDataRC[:, itemIndex])\n",
    "        simSum = float(simSum + sim)\n",
    "        simSumScore = simSumScore + userScore * sim\n",
    "    if simSum == 0:\n",
    "        return 0\n",
    "    return simSumScore / simSum\n",
    "\n",
    "\n",
    "U, sigma, VT = np.linalg.svd(scoreData)\n",
    "\n",
    "sigmaSum = 0\n",
    "k_num = 0\n",
    "for k in range(len(sigma)):\n",
    "    sigmaSum = sigmaSum + sigma[k] * sigma[k]\n",
    "    if float(sigmaSum) / float(np.sum(sigma ** 2)) > 0.9:\n",
    "        k_num = k + 1\n",
    "        break\n",
    "\n",
    "sigma_K = np.mat(np.eye(k_num) * sigma[:k_num])\n",
    "scoreDataRC = sigma_K * U.T[:k_num,:] * scoreData\n",
    "\n",
    "n = np.shape(scoreData)[1]\n",
    "userIndex = 17\n",
    "\n",
    "for i in range(n):\n",
    "    userScore = scoreData[17, i]\n",
    "    if userScore != 0:\n",
    "        continue\n",
    "    print(\"index:{},score:{}\".format(i, estScore(scoreData, scoreDataRC, userIndex, i)))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "0\n",
      "0\n"
     ]
    }
   ],
   "source": [
    "from sympy import integrate, cos, sin\n",
    "from sympy.abc import x\n",
    "import numpy as np\n",
    "\n",
    "e1 = integrate(sin(2*x)*cos(5*x), (x, 0, 2*np.pi))\n",
    "e2 = integrate(sin(4*x)*cos(0*x), (x, 0, 2*np.pi))\n",
    "e3 = integrate(sin(x)*cos(2*x), (x, 0, 2*np.pi))\n",
    "print(e1.evalf())\n",
    "print(e2.evalf())\n",
    "print(e3.evalf())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-2.44929359829471e-16\n"
     ]
    }
   ],
   "source": [
    "from sympy import integrate, cos, sin\n",
    "from sympy.abc import x\n",
    "import numpy as np\n",
    "\n",
    "e1 = integrate(cos(2*x)*cos(5*x), (x, 0, 2*np.pi))\n",
    "print(e1.evalf())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.0\n",
      "5.0\n",
      "(5+6j)\n",
      "(1+13j)\n",
      "(2-1j)\n",
      "2.23606797749979\n"
     ]
    }
   ],
   "source": [
    "z1 = 2 + 1j\n",
    "z2 = 3 + 5j\n",
    "print(z1.real)\n",
    "print(z2.imag)\n",
    "print(z1+z2)\n",
    "print(z1*z2)\n",
    "print(z1.conjugate())\n",
    "print(abs(z1))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
